package cn.bonoon.services.plugins;

import java.util.Date;
import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import cn.bonoon.core.plugins.AccountProxyService;
import cn.bonoon.entities.AccountProxyLog;
import cn.bonoon.entities.AccountProxyRuleEntity;
import cn.bonoon.kernel.security.LogonUser;
import cn.bonoon.kernel.security.LogonUserProxyable;
import cn.bonoon.kernel.support.services.ServiceSupport;

@Service
@Transactional(readOnly = true)
public class AccountProxyServiceImpl extends ServiceSupport implements AccountProxyService {

	@Override
	@Transactional
	public void validate(LogonUserProxyable user, String proxyPwd, LogonUser target) {
		// TODO 全部可代理
		Assert.isTrue(!target.isSuper(), "无法代理超级管理员的账号！");
		
		LogonUser sourceUser = user.getLogonUser();
		Assert.isTrue(!sourceUser.getId().equals(target.getId()), "不能代管自己的账号");
		
		String ql = "select x from AccountProxyRuleEntity x where x.deleted=false and x.account.id=? order by x.priority asc";
		List<AccountProxyRuleEntity> rules = __list(AccountProxyRuleEntity.class, ql, sourceUser.getId());
		
		Assert.notEmpty(rules, "没有定义当前用户[" + user.getUsername() + "]的代管规则！");
		boolean passed = false;
		LOOP : for(AccountProxyRuleEntity rule : rules){
			switch (validateRule(rule, proxyPwd, target)) {
			case SINGLE:
				//如果验证通过，并且不需要再继续验证的，则在这里可以退出了
				passed = true;
				break LOOP;
			case MULTIPLE:
				//验证通过，但必须保存没有禁止的情况
				passed = true;
				break;
			case ERROR:
				//只要有异常，则前面的验证都会被忽略，这个异常规定了必须退出
				passed = false;
				break LOOP;
			default:
				break;
			}
		}
		
		Assert.isTrue(passed, "不能代管账号[" + target.getUsername() + "]");
		
		proxySuccess(sourceUser, target);
	}
	
	/** 成功代管了某个账户，则需要记录一些日志信息 */
	private void proxySuccess(LogonUser sourceUser, LogonUser targetUser){
		AccountProxyLog proxyLog = new AccountProxyLog();
		proxyLog.setCreateAt(new Date());
		proxyLog.setCreatorId(sourceUser.getId());
		proxyLog.setUserName(sourceUser.getUsername());
		proxyLog.setContent("代管账号");
		proxyLog.setProxyId(targetUser.getId());
		proxyLog.setProxyName(targetUser.getUsername());
		entityManager.persist(proxyLog);
	}
	
	enum AccountProxyruleReulstType{
		/** 这条规则在这里不起作用，如超时、验证码不正确等情况 */
		NONE,
		/** 表示验证不通过，则需要继续验证 */
		ERROR,
		/** 验证通过，并且只需要这条通过即可 */
		SINGLE,
		/** 验证通过，并且需要保存后面规则里没有拒绝的规则 */
		MULTIPLE;
	}
	
	/** 验证规则 */
	private AccountProxyruleReulstType validateRule(AccountProxyRuleEntity rule, String proxyPwd, LogonUser target){ 
		String key = parseProxyPassword(proxyPwd);
		if(!key.equals(rule.getPassword())){
			return AccountProxyruleReulstType.NONE; 
		}
		
		//
		return AccountProxyruleReulstType.SINGLE;
	}

	/** 是否需要使用MD5进行加密，暂时就不需要了 */
	private String parseProxyPassword(String proxyPwd){
		return proxyPwd;
	}
}
